package com.zhdl.hardware.clamping_jaw.micro.repository.impl;

import cn.hutool.core.util.HexUtil;
import com.google.common.eventbus.Subscribe;
import com.project.command.faq.event.behavior.BehaviorPerform;
import com.project.command.instruction.strategy.process.data.AfterStrategyParam;
import com.project.common.util.ByteHelper;
import com.project.common.util.CRC16;
import com.zhdl.common.eventbus.center.EventBusCenter;
import com.zhdl.hardware.clamping_jaw.micro.repository.MicroCmdHandleDao;
import com.zhdl.modules.tools.CommonCallback;
import com.zhdl.network.asciirtu.dto.AsciiRtuDto;
import com.zhdl.network.modbusrtu.dto.ModbusDto;
import com.zhdl.network.strategy.common.ProtocolContext;
import com.zhdl.network.strategy.modbusrtu.AsciiRtuStrategy;
import com.zhdl.network.strategy.modbusrtu.ModbusRtuStrategy;
import com.zhdl.network.strategy.modbustcp.ModbusASCIIStrategy;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class MicroCmdHandleDaoImpl implements MicroCmdHandleDao {
    /**
     * Micro电机-串口
     */
    public String port;
    /**
     * 通信协议处理
     */
    public ProtocolContext protocolContext;
    /**
     * Callback 回调管理
     */
    public Map<String, CommonCallback<byte[]>> commonCallbackMap = new ConcurrentHashMap<>();

    public MicroCmdHandleDaoImpl(String port, BehaviorPerform behaviorPerform) {
        EventBusCenter.getEventBus().register(this);
        protocolContext = new ProtocolContext(new AsciiRtuStrategy(port, behaviorPerform));
        this.port = port;
    }

    @Subscribe
    public void dataReception(AfterStrategyParam event) {

        /* 判断当前串口 */
        if (port.equals(event.getPortKey())) {
            /* 获取电机指令返回的数据 */
            //此处接收串口或网口客户端回应代码,并处理
            List<AsciiRtuDto> list = event.getNewData();
            AsciiRtuDto asciiRtuDto = list.get(0);

            String instruction = event.getInstruction();
            instruction = instruction.replaceAll(" ", "");
            instruction = instruction.toUpperCase();
            for (String cmd : commonCallbackMap.keySet()) {
                String temp = cmd.toUpperCase();
                if (temp.contains(instruction)) {
                    commonCallbackMap.get(cmd).statusCallback(asciiRtuDto.getUnitBuff());
                    commonCallbackMap.remove(cmd);
                }
            }
        }

    }

    /**
     * Micro电机-电机通用指令调试
     *
     * @param cmd 完整指令
     * @param callback 回调
     */
    @Override
    public void microGenericCmd(String cmd, CommonCallback<byte[]> callback){
        char[] charArray = cmd.toCharArray();
        StringBuffer stringBuffer = new StringBuffer();
        for (char c : charArray) {
            stringBuffer.append(Integer.toHexString(c));
        }
        String hexStr = stringBuffer.toString();

        byte[] bytes = ByteHelper.hex2byte(hexStr);

        byte[] crcByte = CRC16.MODBUS(bytes);

        String crc16 = ByteHelper.bytesArrayToHexString(crcByte);

        hexStr = hexStr + crc16 + "0D0A";

        protocolContext.sendCmd(hexStr);
        log.info("Micro电机-发送自定义指令：" + hexStr);
        commonCallbackMap.put(hexStr, callback);
    }
}
